home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Applications / Fixation 1.3 / fastmap.cpp < prev    next >
Text File  |  1996-01-28  |  14KB  |  451 lines

  1. // fastmap.cpp
  2.  
  3. // lots of fun assumtions ;-j
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include "error.h"
  8.  
  9. //#include "Utilities.h"
  10. #include "fastmap.h"
  11.  
  12. extern GWorldPtr boff;
  13.  
  14.     // gworld must have bits locked
  15. Fastmap::Fastmap( GWorldPtr gw, Boolean isMasked, short index, short hsize, short vsize )
  16. {
  17.     PixMapHandle pmh = GetGWorldPixMap(gw); verify(pmh);
  18.     long *src, *dst;
  19.     src = (long *) GetPixBaseAddr(pmh); verify(src);
  20.     StripAddress(src);
  21.     
  22.     masked = isMasked;
  23.     
  24.     width = hsize;
  25.     if (width & 3) Debugger();
  26.     if (width == 0) {
  27.         width = (**pmh).bounds.right;
  28.         if (width & 3) Debugger();
  29.         if (masked)
  30.             width /= 2;
  31.     }
  32.     
  33.     height = (**pmh).bounds.bottom;
  34.     if (vsize)
  35.         height = vsize;
  36.     
  37.     long dataSize = (long) height * width;
  38.     if (masked)
  39.         dataSize *= 2;        // need room for mask, which is mixed in
  40.     bits = (long *) NewPtr(dataSize); verify(bits);
  41.     
  42.         // now we copy the picture from the gworld to our memory
  43.     long srcrb, soffset, loopoffset;
  44.     int rowlongs, loop;
  45.     long startx, endx;
  46.  
  47.     dst = bits;
  48.     
  49.     srcrb = (**pmh).rowBytes & 0x3fff;
  50.     startx = index * width;
  51.     endx = startx + width;
  52.  
  53.         // set up offsets
  54.     soffset = startx;
  55.     src = (long *) ((long) src + soffset);
  56.      rowlongs = (endx - startx) >> 2;
  57.    
  58.         // prepare for loop
  59.     loop = height;
  60.     loopoffset = srcrb - (rowlongs << 2);
  61.     
  62.         // copy the pix
  63.     short nnn;
  64.     
  65.     if (!masked)
  66.         while (loop-- > 0) {
  67.             for (nnn = 0; nnn < rowlongs; nnn++)
  68.                 *dst++ = *src++;
  69.     //        dst = (long *) (((long) dst) + loopoffset);
  70.             src = (long *) (((long) src) + loopoffset);
  71.         }
  72.     else {
  73.         long val, msk;
  74.         while (loop-- > 0) {
  75.             for (nnn = 0; nnn < rowlongs; nnn++) {
  76.                 val = *src++;
  77.                     // we make mask ourselves -- all whitespace is not mask
  78.                 msk = 0;
  79.                 if ((val & 0xFF000000) == 0) msk = 0xFF000000;
  80.                 if ((val & 0x00FF0000) == 0) msk |= 0x00FF0000;
  81.                 if ((val & 0x0000FF00) == 0) msk |= 0x0000FF00;
  82.                 if ((val & 0x000000FF) == 0) msk |= 0x000000FF;
  83.                 val |= msk;        // change those zeroes to FF's
  84.                 msk = msk ^ 0xFFFFFFFF;        // flip mask, chump
  85.                 *dst++ = val;
  86.                 *dst++ = msk;
  87.             }
  88.             src = (long *) ((long) src + loopoffset);
  89.         }
  90.     }
  91. }
  92.  
  93. void
  94. Fastmap::Draw8by8Mask(GWorldPtr destworld, Rect *r)
  95. {
  96.     PixMapPtr dstpm;
  97.     long *src, *dst, dest;
  98.     long dstrb, dstrbm4;
  99.     short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
  100.     
  101.     if (r->left < 0 || r->top < 0 || r->right > winwidth || r->bottom > winheight)
  102.         return;        // avoid writing over someone else's memory
  103.         
  104.     src = bits;
  105.  
  106.     dstpm = *destworld->portPixMap;
  107.     dest = (long) dstpm->baseAddr;
  108.     dstrb = dstpm->rowBytes & 0x3fff;
  109.     dstrbm4 = dstrb - 4;
  110.     dest += r->left;
  111.     dest += r->top * dstrb;
  112.     dst = (long *) dest;
  113.     
  114.         // copy the pix
  115.     short nnn = height;
  116.     long tmp, msk, val;
  117.     while (nnn--) {
  118.         val = *src++;
  119.         tmp = *dst;
  120.         msk = *src++;
  121.         tmp |= msk;
  122.         tmp &= val;
  123.         *dst++ = tmp;
  124.         
  125.         val = *src++;
  126.         tmp = *dst;
  127.         msk = *src++;
  128.         tmp |= msk;
  129.         tmp &= val;
  130.         *dst = tmp;
  131.         
  132.         dst = (long *) ((long) dst + dstrbm4);
  133.     }
  134. }
  135.  
  136. void
  137. Fastmap::DrawMask(GWorldPtr destworld, Rect *r)
  138. {
  139. //    PixMapPtr dstpm;
  140.     PixMapHandle pmh = GetGWorldPixMap(destworld);
  141.     register long *src, *dst;
  142.     long dest;
  143.     long dstrb;
  144.     short loop, copyLongs, srcDelta, leftStub;
  145.     short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
  146.     
  147.     if (r->right < 0 || r->bottom < 0 || r->left >= winwidth || r->top >= winheight)
  148.         return;        // avoid writing over someone else's memory
  149.         
  150.     verify(r->right - r->left == width && r->bottom - r->top == height);
  151.         
  152.     src = bits;
  153.  
  154.     dest = (long) GetPixBaseAddr(pmh);  verify(dest); StripAddress((void *) dest);
  155.     dstrb = (**pmh).rowBytes & 0x3fff;
  156.     dest += r->left;
  157.     dest += r->top * dstrb;
  158.     dst = (long *) dest;
  159.     
  160.     loop = height;
  161.     copyLongs = width >> 2;
  162.     srcDelta = 0;
  163.     if (r->top < 0) {        // runs off top of screen
  164.         short offs = -(r->top);
  165.         src = (long *) ((long) src + ((offs * width) << 1));        // offset source
  166.         dst = (long *) ((long) dst + offs * dstrb);        // offset dest
  167.         loop -= offs;
  168.     }
  169.     if (r->bottom > winheight) {        // runs off bottom of screen
  170.         loop -= r->bottom - winheight;
  171.     }
  172.     if (r->left < 0) {        // runs off top of screen
  173.         short offs = -(r->left);
  174.             // square up
  175.         leftStub = offs & 3;
  176.         if (leftStub) offs += (4 - leftStub);
  177.         offs -= 4;        // somehow this doesn't crash it
  178.         
  179.         src = (long *) ((long) src + (offs << 1));        // offset source
  180.         dst = (long *) ((long) dst + offs);        // offset dest
  181.         
  182.         copyLongs -= offs >> 2;
  183.         srcDelta += offs;
  184.     }
  185.     if (r->right > winwidth) {        // runs off right of screen
  186.             // we're going to let it run over for now, assume gworld has more rowbytes than should
  187.         short offs = r->right - winwidth;
  188.             // square up
  189.          offs -= offs & 3;
  190.          
  191.         copyLongs -= offs >> 2;
  192.         srcDelta += offs;
  193.     }
  194.     
  195.     if (copyLongs <= 0) return;        // nuttin' to copy
  196.     
  197.         // copy the pix
  198.     register long tmp, msk, val;
  199.     long dstDelta;
  200.     dstDelta = dstrb - (copyLongs << 2);
  201.     srcDelta <<= 1;
  202.     
  203.   /*  if (leftStub) {
  204.             // okay, we have to patch up the left column
  205.             // this sux, but we only rarely have to do it, and it shouldn't be too slow
  206.             // this will eventually be made moot
  207.         short myLoop = loop;
  208.         long *oldDest = dst, *oldSrc = src;
  209.         
  210.         
  211.         
  212.         while (loop--) {
  213.             val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  214.             dst = (long *) ((long) dst + dstDelta);
  215.             src = (long *) ((long) src + srcDelta);
  216.         }
  217.         
  218.         dst = oldDest; src = oldSrc;
  219.     }*/
  220.     
  221.     while (loop--) {
  222.         switch (copyLongs) {
  223.             case 24:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  224.             case 23:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  225.             case 22:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  226.             case 21:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  227.             case 20:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  228.             case 19:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  229.             case 18:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  230.             case 17:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  231.             case 16:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  232.             case 15:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  233.             case 14:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  234.             case 13:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  235.             case 12:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  236.             case 11:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  237.             case 10:        val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  238.             case 9:         val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  239.             case 8:         val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  240.             case 7:         val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  241.             case 6:         val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  242.             case 5:         val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  243.             case 4:         val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  244.             case 3:         val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  245.             case 2:         val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  246.             case 1:         val = *src++;tmp = *dst;msk = *src++;tmp |= msk;tmp &= val;*dst++ = tmp;
  247.             case 0:            break;
  248. //            default: DebugPrint(srcRect->right - srcRect->left); verify(false);
  249.         }
  250.         dst = (long *) ((long) dst + dstDelta);
  251.         src = (long *) ((long) src + srcDelta);
  252.     }
  253. }
  254.  
  255.  
  256. void
  257. Fastmap::Draw(GWorldPtr destworld, Rect *r)
  258. {
  259.     PixMapPtr dstpm;
  260.     PixMapHandle pmh = destworld->portPixMap;
  261.     register long *src, *dst;
  262.     long dest;
  263.     long dstrb;
  264.     short loop, copyLongs, srcDelta, leftStub;
  265.     short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
  266.     
  267.     if (r->right < 0 || r->bottom < 0 || r->left >= winwidth || r->top >= winheight)
  268.         return;        // avoid writing over someone else's memory
  269.         
  270.     verify(r->right - r->left == width && r->bottom - r->top == height);
  271.         
  272.     src = bits;
  273.  
  274.     dstpm = *destworld->portPixMap;
  275.     dest = (long) GetPixBaseAddr(pmh);  verify(dest); StripAddress((void *) dest);
  276.     dstrb = dstpm->rowBytes & 0x3fff;
  277.     dest += r->left;
  278.     dest += r->top * dstrb;
  279.     dst = (long *) dest;
  280.     
  281.     loop = height;
  282.     copyLongs = width >> 2;
  283.     srcDelta = 0;
  284.     if (r->top < 0) {        // runs off top of screen
  285.         short offs = -(r->top);
  286.         src = (long *) ((long) src + ((offs * width) << 1));        // offset source
  287.         dst = (long *) ((long) dst + offs * dstrb);        // offset dest
  288.         loop -= offs;
  289.     }
  290.     if (r->bottom > winheight) {        // runs off bottom of screen
  291.         loop -= r->bottom - winheight;
  292.     }
  293.     if (r->left < 0) {        // runs off top of screen
  294.         short offs = -(r->left);
  295.             // square up
  296.         leftStub = offs & 3;
  297.         if (leftStub) offs += (4 - leftStub);
  298.         offs -= 4;        // somehow this doesn't crash it
  299.         
  300.         src = (long *) ((long) src + (offs << 1));        // offset source
  301.         dst = (long *) ((long) dst + offs);        // offset dest
  302.         
  303.         copyLongs -= offs >> 2;
  304.         srcDelta += offs;
  305.     }
  306.     if (r->right > winwidth) {        // runs off right of screen
  307.             // we're going to let it run over for now, assume gworld has more rowbytes than should
  308.         short offs = r->right - winwidth;
  309.             // square up
  310.          offs -= offs & 3;
  311.          
  312.         copyLongs -= offs >> 2;
  313.         srcDelta += offs;
  314.     }
  315.     
  316.     if (copyLongs <= 0) return;        // nuttin' to copy
  317.     
  318.         // copy the pix
  319.     long dstDelta;
  320.     dstDelta = dstrb - (copyLongs << 2);
  321.     srcDelta <<= 1;
  322.     
  323.     while (loop--) {
  324.         switch (copyLongs) {
  325.                 case 24:        *dst++ = *src++;
  326.                 case 23:        *dst++ = *src++;
  327.                 case 22:        *dst++ = *src++;
  328.                 case 21:        *dst++ = *src++;
  329.                 case 20:        *dst++ = *src++;
  330.                 case 19:        *dst++ = *src++;
  331.                 case 18:        *dst++ = *src++;
  332.                 case 17:        *dst++ = *src++;
  333.                 case 16:        *dst++ = *src++;
  334.                 case 15:        *dst++ = *src++;
  335.                 case 14:        *dst++ = *src++;
  336.                 case 13:        *dst++ = *src++;
  337.                 case 12:        *dst++ = *src++;
  338.                 case 11:        *dst++ = *src++;
  339.                 case 10:        *dst++ = *src++;
  340.                 case 9:         *dst++ = *src++;
  341.                 case 8:         *dst++ = *src++;
  342.                 case 7:         *dst++ = *src++;
  343.                 case 6:         *dst++ = *src++;
  344.                 case 5:         *dst++ = *src++;
  345.                 case 4:         *dst++ = *src++;
  346.                 case 3:         *dst++ = *src++;
  347.                 case 2:         *dst++ = *src++;
  348.                 case 1:         *dst++ = *src++;
  349.                 case 0:            break;
  350. //            default: DebugPrint(srcRect->right - srcRect->left); verify(false);
  351.         }
  352.         dst = (long *) ((long) dst + dstDelta);
  353.         src = (long *) ((long) src + srcDelta);
  354.     }
  355. }
  356.  
  357. void
  358. Fastmap::Draw8by8(GWorldPtr destworld, Rect *r)
  359. {
  360.     if (masked) {
  361.         Draw8by8Mask(destworld, r);
  362.         return;
  363.     }
  364.  
  365.     PixMapPtr dstpm;
  366.     PixMapHandle pmh;
  367.     long *src, *dst, dest;
  368.     long dstrb, dstrbm4;
  369.     short winwidth = destworld->portRect.right, winheight = destworld->portRect.bottom;
  370.     
  371.     if (r->left < 0 || r->top < 0 || r->right > winwidth || r->bottom > winheight)
  372.         return;        // avoid writing over someone else's memory
  373.         
  374.     src = bits;
  375.  
  376.     dstpm = *destworld->portPixMap;
  377.     dest = (long) dstpm->baseAddr;
  378.     dstrb = dstpm->rowBytes & 0x3fff;
  379.     dstrbm4 = dstrb - 4;
  380.     dest += r->left;
  381.     dest += r->top * dstrb;
  382.     dst = (long *) dest;
  383.     
  384.         // copy the pix
  385.     *dst++ = *src++;    *dst = *src++;
  386.     dst = (long *) ((long) dst + dstrbm4);
  387.     *dst++ = *src++;    *dst = *src++;
  388.     dst = (long *) ((long) dst + dstrbm4);
  389.     *dst++ = *src++;    *dst = *src++;
  390.     dst = (long *) ((long) dst + dstrbm4);
  391.     *dst++ = *src++;    *dst = *src++;
  392.     dst = (long *) ((long) dst + dstrbm4);
  393.     *dst++ = *src++;    *dst = *src++;
  394.     dst = (long *) ((long) dst + dstrbm4);
  395.     *dst++ = *src++;    *dst = *src++;
  396.     dst = (long *) ((long) dst + dstrbm4);
  397.     *dst++ = *src++;    *dst = *src++;
  398.     dst = (long *) ((long) dst + dstrbm4);
  399.     *dst++ = *src++;    *dst = *src;
  400. }
  401.  
  402. //extern GDHandle maindev;
  403. //extern WindowPtr myWindow;
  404.  
  405.  
  406. void LoadFastmaps(short baseID, short num, frameData *frameCounts, Rect *blockrect, Fastmap **bpix, short maxFrames)
  407. {
  408.     short nnn;
  409.     Rect r;
  410.     PicHandle p;
  411.         
  412.     verify(bpix);
  413.     verify(boff);
  414.     SetGWorld(boff, nil);        // our scratch space
  415.     
  416.     for (nnn = 0; nnn < num; nnn++) {
  417.         p = GetPicture(nnn + baseID);
  418.         if (!p)
  419.             verify(false);        // forget this one
  420.             
  421.         r = (**p).picFrame;
  422.         OffsetRect(&r, -r.left, -r.top);
  423.         verify(frameCounts[nnn].frames);
  424.         verify(r.right % frameCounts[nnn].frames == 0);    // reasonably safe check of frames
  425.         blockrect[nnn] = r;
  426.         blockrect[nnn].right /= frameCounts[nnn].frames;
  427.         verify((blockrect[nnn].right & 3) == 0);        // must be long-aligned
  428.         
  429.             // paint the picture into scratch
  430.         EraseRect(&r);
  431.         DrawPicture(p, &r);
  432.         ReleaseResource((Handle) p);
  433.  
  434.  
  435. /*
  436.         verify(myWindow);
  437.         SetGWorld((GWorldPtr) myWindow, maindev);
  438.         CopyBits ((BitMap *) *(boff->portPixMap), (BitMap *) *(((CWindowPtr) myWindow)->portPixMap),
  439.         &r, &r, srcCopy, nil);
  440.         SetGWorld(boff, nil);
  441.         Debugger();
  442. */
  443.         
  444.         for (short mmm = 0; mmm < frameCounts[nnn].frames; mmm++) {
  445.                 // make fast map and copy pic in
  446.             bpix[nnn*maxFrames+mmm] = new Fastmap(boff, frameCounts[nnn].masked,
  447.                     mmm, blockrect[nnn].right, blockrect[nnn].bottom);
  448.             verify(bpix[nnn*maxFrames+mmm]);
  449.         }
  450.     }
  451. }